using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;

namespace SiliverlightJavascriptIntelli
{
    public static class TypeHelper
    {
        private static Assembly _agClrAssembly;
        public static Assembly agClrAssembly
        {
            get
            {
                if (_agClrAssembly == null)
                    _agClrAssembly = Assembly.LoadFrom(@"C:\Program Files\Microsoft Silverlight\agclr.dll");

                return _agClrAssembly;
            }
        }

        public static string ConvertTypeToString(Type type)
        {
            if (type == null)
                return null;
            if (type.Name == "Void")
                return null;
            if (IsTypeInteger(type))
                return "Number";
            if (type.Name == "EventHandler")
                return "Function";
            if (type.Name.StartsWith("Nullable"))
                return type.GetGenericArguments()[0].Name;
            if (type.Name.StartsWith("Collection") && type.IsGenericType)
                return "Collection";
            if (type.Name == "Image")
                return "ImageSL";
            if (type.Name.ToUpper() == "URI")
                return "String";
            if (type.Name == "TimeSpan")
                return "String";
            return type.Name;
        }

        public static bool IsTypeNumber(Type type)
        {
            string[] TypeNumberName = new string[] { "Int16", "Int32", "Int64", "decimal", "Double", "Number" };
            return ((IList)TypeNumberName).Contains(type.Name);
        }

        public static bool IsTypeInteger(Type type)
        {
            return IsTypeInteger(type.Name);
        }

        public static bool IsTypeInteger(string type)
        {
            string[] TypeNumberName = new string[] { "Int16", "Int32", "Int64", "Number" };
            return ((IList)TypeNumberName).Contains(type);
             
        }

        public static bool IsFromUIElement(Type from)
        {
            return (from.IsSubclassOf(agClrAssembly.GetType("System.Windows.FrameworkElement")));

        }

        private static List<SilverlightType> _knownTypesAfterDiscovery = new List<SilverlightType>();
        private static List<string> myList = new List<string>();

        public static List<SilverlightType> KnownTypesAfterDiscovery
        {
            get { return _knownTypesAfterDiscovery; }
            set { _knownTypesAfterDiscovery = value; }
        }

        public static string UIElement
        {
            get
            {
                return "UIElement";
            }
        }

        public static bool IsKnownTypeBy(string Name)
        {
            if (Name == null)
                return false;
            bool ReturnValue = KnownTypesAfterDiscovery.Exists(delegate(SilverlightType type)
                                              {
                                                  return type.Name.ToLower() == Name.ToLower();
                                              });
            if (!ReturnValue && (!myList.Contains(Name)))
            {
                myList.Add(Name);
            }

            return ReturnValue;
        }

        public static string GetConvertToPrefixForType(string type)
        {
            string ConvertToPrefix = null;
            if (TypeHelper.IsKnownTypeBy(type))
                ConvertToPrefix = StringHelper.Format(JavascriptFormats.ConvertToPrefix, type);
            return ConvertToPrefix;
        }

        public static void GetAllTypesInhertingFromThisClass(Type from, List<string> hierchy)
        {
            hierchy.Add(TypeHelper.ConvertTypeToString(from));
            foreach (Type TypeToCheckIfInehritsFrom in _agClrAssembly.GetTypes())
            {
                if (TypeToCheckIfInehritsFrom.IsSubclassOf(from))
                    hierchy.Add(TypeHelper.ConvertTypeToString(TypeToCheckIfInehritsFrom));
            }
        }

        public static string GetExtractFromPrefixFor(string type)
        {
            if (TypeHelper.IsKnownTypeBy(type))
                return StringHelper.Format(JavascriptFormats.ExtractFromWrapper, type);
            return null;
        }


        public static bool IsFromDependencyObject(Type from)
        {
            return (from == agClrAssembly.GetType("System.Windows.DependencyObject"))
                    ||(from.IsSubclassOf(agClrAssembly.GetType("System.Windows.DependencyObject")));
        }

        public static bool IsFromDependencyProperty(Type from)
        {
            return (from == agClrAssembly.GetType("System.Windows.DependencyProperty"))
                    || (from.IsSubclassOf(agClrAssembly.GetType("System.Windows.DependencyProperty")));
            
        }

        public static bool IsEnum(Type from)
        {
            return from.IsEnum;
        }

        public static SilverlightType GetSilverlightKnownTypeByName(string nameToSearchFor)
        {
            SilverlightType ReturnValue = TypeHelper.KnownTypesAfterDiscovery.Find(delegate(SilverlightType curType)
                                                                                       {
                                                                                           return (curType.Name == nameToSearchFor);
                                                                                       });
            return ReturnValue;
        }

        public static List<SilverlightType> GetKnownTypesInheritingFrom(SilverlightType typeToReturnAllTypesInehritingFrom)
        {
            return TypeHelper.KnownTypesAfterDiscovery.FindAll(delegate(SilverlightType typeToCheckIfInheritsFrom)
                                                                   {
               return typeToCheckIfInheritsFrom.IsSubTypeOrEquealTypeTo(typeToReturnAllTypesInehritingFrom);
                                                                   });
        }


    }
}